package antonst.dcl;

import java.io.File;
import java.util.Arrays;

public class ClassReloader implements Runnable {

	private final String nameOfClassToReload;
	private final File javaSourceFileToReload;
	private final CustomCompiller compiller = new CustomCompiller();
	private long lastModified;

	public ClassReloader(String nameOfClassToReload) {
		this.nameOfClassToReload = nameOfClassToReload;
		String javaSourceFilePath = "src/" + nameOfClassToReload.replace(".", "/") + ".java";
		javaSourceFileToReload = new File(javaSourceFilePath);
		fixLastModifiedTime();
	}

	public void startMonitoringInCurrentThread() {
		this.run();
	}
	
	@Override
	public void run() {
		while (true) {
			if ((javaSourceFileToReload.exists())
					&& (lastModified != javaSourceFileToReload.lastModified())) {
				recompileJavaSource();
				Class<?> reloadedClass = reloadClass();
				testModule(reloadedClass);
				fixLastModifiedTime();
			}
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	private void fixLastModifiedTime() {
		if (javaSourceFileToReload.exists()) {
			lastModified = javaSourceFileToReload.lastModified();
		}
	}
	
	private Class reloadClass(){
		Class<?> classToReload = null;
		DynamicClassLoader dynamicLoader = new DynamicClassLoader(
						ClassReloader.class.getClassLoader());
		dynamicLoader.addDynamicClassName(nameOfClassToReload);
		try {
			classToReload = Class.forName(nameOfClassToReload,
				true, dynamicLoader);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return classToReload;
	}
	
	private void testModule(Class<?> testModuleClass) {
		try {
		Object testModule = testModuleClass.newInstance();
		System.out.println(testModule);
		} catch(InstantiationException | IllegalAccessException e){
			e.printStackTrace();
		}
	}
	
	private void recompileJavaSource() {
		Iterable<? extends File> files = Arrays.asList(new File[]{ javaSourceFileToReload });
		new CustomCompiller().recompile(files);
		compiller.recompile(files);
	}

}
